/**********************************************
** @Des: base controller
** @Author: haodaquan
** @Date:   2017-09-07 16:54:40
** @Last Modified by:   haodaquan
** @Last Modified time: 2017-09-18 10:28:01
***********************************************/
package controllers

import (
	"newAi/new_web/libs"
	"newAi/new_web/models"
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"

	"bufio"
	"io"
	"os/exec"

	"github.com/satori/go.uuid"
)

const (
	MSG_OK  = 0
	MSG_ERR = -1
)

type User_group struct {
	Id        int
	LoginName string
}

type BaseController struct {
	beego.Controller
	controllerName string
	actionName     string
	user           *models.Admin
	userId         int
	isOrg          bool
	userName       string
	loginName      string
	pageSize       int
	allowUrl       string
}

//前期准备
func (self *BaseController) Prepare() {
	self.userId = 1
	return
	self.pageSize = 40
	controllerName, actionName := self.GetControllerAndAction()
	self.controllerName = strings.ToLower(controllerName[0 : len(controllerName)-10])
	self.actionName = strings.ToLower(actionName)
	self.Data["version"] = beego.AppConfig.String("version")
	self.Data["siteName"] = beego.AppConfig.String("site.name")
	self.Data["curRoute"] = self.controllerName + "." + self.actionName
	self.Data["curController"] = self.controllerName
	self.Data["curAction"] = self.actionName
	noAuth := "ajaxsave/ajaxdel/table/loginin/loginout/getnodes/start"
	isNoAuth := strings.Contains(noAuth, self.actionName)
	if isNoAuth == false {
		self.auth()
	}
	self.Data["loginUserId"] = self.userId
	self.Data["loginUserName"] = self.userName
}

//登录权限验证
func (self *BaseController) auth() {
	arr := strings.Split(self.Ctx.GetCookie("auth"), "|")
	self.userId = 0
	if len(arr) == 3 {
		idstr, password, orgstr := arr[0], arr[1], arr[2]
		userId, _ := strconv.Atoi(idstr)
		is_org, _ := strconv.ParseBool(orgstr)
		if userId > 0 {
			user, err := models.AdminGetById(userId)
			if err == nil && password == libs.Md5([]byte(self.getClientIp()+"|"+user.Password+user.Salt)) {
				self.userId = user.Id
				self.isOrg = is_org
				self.loginName = user.LoginName
				self.userName = user.RealName
				self.user = user
			}
			if self.AdminAuth() {
				self.redirect("/login_out")
				self.Ctx.WriteString("登录权限过期，请重新登录")
				return
			}

			isHasAuth := strings.Contains(self.allowUrl, self.controllerName+"/"+self.actionName)

			noAuth := "ajaxsave/ajaxdel/table/seattable/loginin/loginout/getnodes/getprocesscontent/start/adminstart/testcall" +
				"/setmute/contentdel/processcontentsave/updatekeyword/processcontentupdate/searchcdr/exportexsel/gettplbyprocessid" +
				"/getimmessage/getimnodemessage/searchview/tablelist/addglobal/getimlistinfo/show/ajaxapisave/aitarget" +
				"/stoptask/txtimport/setnodeposition/runtimelist/searchcdrstute/notmatchlist/contenttableone/flowcdr" +
					"/deletenotmatch/contenttablealllist/seatadd/extensionadd/explain/seataddno/gethomeinfo/getsorttask/ajaxdatchdel" +
						"/copynodepercess"

			isNoAuth := strings.Contains(noAuth, self.actionName)
			if isHasAuth == false && isNoAuth == false {
				self.Ctx.WriteString("没有权限")
				self.ajaxMsg("没有权限", MSG_ERR)
				return
			}
		}
	}
	if self.userId == 0 && (self.controllerName != "login" && self.actionName != "loginin") {
		self.redirect(beego.URLFor("LoginController.LoginIn"))
	}
}

func (self *BaseController) AdminAuth() bool {
	// 左侧导航栏
	filters := make([]interface{}, 0)
	filters = append(filters, "status", 1)
	fmt.Println("------admin auth ids-----", self.user)
	if self.userId != 1 {
		//普通管理员
		if self.user == nil {
			return true
		}
		if time.Now().Unix() > self.user.Exp_time {
			user, _ := models.AdminGetByName(self.user.LoginName)
			user.Status = 0
			if err := user.Update(); err != nil {
				self.ajaxMsg(err.Error(), MSG_ERR)
			}
			return true
		}
		adminAuthIds, _ := models.RoleAuthGetByIds(self.user.RoleIds)

		adminAuthIdArr := strings.Split(adminAuthIds, ",")
		filters = append(filters, "id__in", adminAuthIdArr)
	}
	result, _ := models.AuthGetList(1, 1000, filters...)
	list := make([]map[string]interface{}, len(result))
	list2 := make([]map[string]interface{}, len(result))
	allow_url := ""
	i, j := 0, 0
	for _, v := range result {
		if v.AuthUrl != " " || v.AuthUrl != "/" {
			allow_url += v.AuthUrl
		}
		row := make(map[string]interface{})
		if v.Pid == 1 && v.Is_show == 1 {
			row["Id"] = int(v.Id)
			row["Sort"] = v.Sort
			row["AuthName"] = v.AuthName
			row["AuthUrl"] = v.AuthUrl
			row["Icon"] = v.Icon
			row["Pid"] = int(v.Pid)
			list[i] = row
			i++
		}
		if v.Pid != 1 && v.Is_show == 1 {
			row["Id"] = int(v.Id)
			row["Sort"] = v.Is_show
			row["AuthName"] = v.AuthName
			row["AuthUrl"] = v.AuthUrl
			row["Icon"] = v.Icon
			row["Pid"] = int(v.Pid)
			list2[j] = row
			j++
		}
	}

	self.Data["SideMenu1"] = list[:i]  //一级菜单
	self.Data["SideMenu2"] = list2[:j] //二级菜单

	self.allowUrl = allow_url + "/home/index"
	return false
}

// 是否POST提交
func (self *BaseController) isPost() bool {
	return self.Ctx.Request.Method == "POST"
}

//获取用户IP地址
func (self *BaseController) getClientIp() string {
	s := strings.Split(self.Ctx.Request.RemoteAddr, ":")
	return s[0]
}

// 重定向
func (self *BaseController) redirect(url string) {
	self.Redirect(url, 302)
	self.StopRun()
}

//加载模板
func (self *BaseController) display(tpl ...string) {
	var tplname string
	if len(tpl) > 0 {
		tplname = strings.Join([]string{tpl[0], "html"}, ".")
	} else {
		tplname = self.controllerName + "/" + self.actionName + ".html"
	}
	self.Layout = "public/layout.html"
	self.TplName = tplname
}

//ajax返回
func (self *BaseController) ajaxMsg(msg interface{}, msgno int) {
	out := make(map[string]interface{})
	out["status"] = msgno
	out["message"] = msg
	self.Data["json"] = out
	self.ServeJSON()
	self.StopRun()
}

//ajax返回
func (self *BaseController) ajaxMessage(msg interface{}, node, msgno int) {
	out := make(map[string]interface{})
	out["status"] = msgno
	out["message"] = msg
	out["node"] = node
	self.Data["json"] = out
	self.ServeJSON()
	self.StopRun()
}

//ajax返回 原有数据
func (self *BaseController) ajaxJson(msg interface{}, msgno int) {
	self.Data["json"] = msg
	self.ServeJSON()
	self.StopRun()
}

//ajax返回 列表
func (self *BaseController) ajaxList(msg interface{}, msgno int, count int64, data interface{}) {
	out := make(map[string]interface{})
	out["code"] = msgno
	out["msg"] = msg
	out["count"] = count
	out["data"] = data
	self.Data["json"] = out
	self.ServeJSON()
	self.StopRun()
}

//时间格式化
func (self *BaseController) FormatTime(strTime string) string {
	toTime, _ := time.Parse("2006-01-02 15:04:05 +0000 +0000", strTime)
	toStr := toTime.Format("2006-01-02 15:04:05")
	return toStr
}

//时间格式化
func (self *BaseController) FormatTimes(strTime string) string {
	toTime, _ := time.Parse("2006-01-02 15:04:05", strTime)
	toStr := toTime.Format("2006-01-02 15:04:05")
	return toStr
}

//上传文件
func (self *BaseController) UploadFile(dir, fileName string) (string, error) {

	timestamp := time.Now().Unix()
	time := strconv.FormatInt(timestamp, 10)
	file, header, err := self.GetFile(fileName) //获取文件
	var str = " "
	var ptsh = time + strconv.FormatInt(int64(rand.Intn(10000)), 10)
	if strings.Contains(header.Filename, ".wav") {
		str = ptsh + ".wav"
	} else if strings.Contains(header.Filename, ".mp3") {
		str = ptsh + ".mp3"
	} else if strings.Contains(header.Filename, ".m4a") {
		str = ptsh + ".m4a"
	} else {
		str = ptsh + ".xlsx"
	}
	path := dir + str //文件目录 暂时'用户信息欠缺

	file.Close() //关闭上传的文件，不然的话会出现临时文件不能清除的情况
	self.SaveToFile(fileName, path)
	//保存文件
	fmt.Println(path)
	if strings.Contains(header.Filename, ".mp3") || strings.Contains(header.Filename, ".m4a") {
		fmt.Println("-i " + path + " " + dir + ptsh + ".wav")
		params := []string{"-i", path, dir + ptsh + ".wav"}
		execCommand("ffmpeg", params)
	}
	if strings.Contains(header.Filename, ".mp3") || strings.Contains(header.Filename, ".m4a") || strings.Contains(header.Filename, ".wav") {
		return dir + ptsh + ".wav", err
	}
	return path, nil
}

func (self *BaseController) ErrorLog(err error) {
	logs.Error(err)
}
func (self *BaseController) CheckError(err error) {
	if err != nil {
		logs.Error(err)
	}
}

func execCommand(commandName string, params []string) bool {
	//函数返回一个*Cmd，用于使用给出的参数执行name指定的程序
	cmd := exec.Command(commandName, params...)

	//显示运行的命令
	fmt.Println(cmd.Args)
	//StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道，一般不需要显式的关闭该管道。
	stdout, err := cmd.StdoutPipe()

	if err != nil {
		fmt.Println(err)
		return false
	}

	cmd.Start()
	//创建一个流来读取管道内内容，这里逻辑是通过一行一行的读取的
	reader := bufio.NewReader(stdout)

	//实时循环读取输出流中的一行内容
	for {
		line, err2 := reader.ReadString('\n')
		if err2 != nil || io.EOF == err2 {
			break
		}
		fmt.Println(line)
	}

	//阻塞直到该命令执行完成，该命令必须是被Start方法开始执行的
	cmd.Wait()
	return true
}

//获取号码组，模板组，网关组，用户组信息到前端页面
func (self *BaseController) SetAllGroup() {

	//group 列表
	num_group, err := models.NumberGroupIdName()
	self.CheckError(err)
	tpl_group, err := models.GetImTplList("tpl")
	self.CheckError(err)
	gw_group, err := models.GatewayGroupIdName()
	self.CheckError(err)
	user_group, err := models.UserGroupIdName()
	self.CheckError(err)
	servers_group, err := models.GetImServersList("servers")
	self.CheckError(err)

	self.Data["num_group"] = num_group
	self.Data["tpl_group"] = tpl_group
	self.Data["gw_group"] = gw_group
	self.Data["user_group"] = user_group
	self.Data["servers_group"] = servers_group
}

//获取号码组，模板组，网关组，用户组信息到前端页面
func (self *BaseController) SetAllGroup1(id int) {

	//group 列表
	num_group, err := models.NumberGroupIdName1(self.userId)
	self.CheckError(err)
	tpl_group, err := models.GetImTplList1("tpl", self.userId)
	self.CheckError(err)
	gw_group, err := models.GatewayGroupIdName1(self.userId)
	self.CheckError(err)

	self.Data["num_group"] = num_group
	self.Data["tpl_group"] = tpl_group
	self.Data["gw_group"] = gw_group
}
func (self *BaseController) SetUserGroup(id int) {

	user_group, err := models.UserGroupBySelfId(id)
	self.CheckError(err)
	self.Data["user_group"] = user_group
}

func (self *BaseController) GetUUId() string {
	// Creating UUID Version 4
	// panic on error
	u1, _ := uuid.NewV4()
	fmt.Printf("UUIDv4: %s\n", u1)
	return u1.String()
}

//func MakeRingPath(basepath, prefix string, ext string, platform string) (string, string) {
//	var nwaypath string
//	now := time.Now()
//	nwaypath = basepath + prefix
//	os.MkdirAll(nwaypath, 777)
//	filename := strconv.Itoa(now.Year()) + strconv.Itoa(int(now.Month())) + strconv.Itoa(now.Day())
//	filename += strconv.Itoa(now.Hour()) + strconv.Itoa(now.Minute()) + strconv.Itoa(now.Second())
//	filename += RandomString(6) + ext
//	nwaypath += filename
//	return nwaypath, filename
//}
